<template>
    <div class="editor-container">
        <Toolbar :editor="editorRef" :mode="mode" />
        <Editor
            :mode="mode"
            :defaultConfig="editorConfig"
            :style="{ height }"
            v-model="state.editorVal"
            @onCreated="handleCreated"
            @onChange="handleChange"
        />
    </div>
</template>

<script setup lang="ts" name="wngEditor">
// https://www.wangeditor.com/v5/for-frame.html#vue3
import "@wangeditor/editor/dist/css/style.css"
import { reactive, shallowRef, watch, onBeforeUnmount } from "vue"
import { IDomEditor } from "@wangeditor/editor"
import { Toolbar, Editor } from "@wangeditor/editor-for-vue"
import { fileUpload } from "@/api/common/common"
import { ElMessage } from "element-plus"
import type { IEditorConfig } from "@wangeditor/core"

// 定义父组件传过来的值
const props = defineProps({
    // 是否禁用
    disable: {
        type: Boolean,
        default: () => false,
    },
    // 内容框默认 placeholder
    placeholder: {
        type: String,
        default: () => "请输入内容...",
    },
    // https://www.wangeditor.com/v5/getting-started.html#mode-%E6%A8%A1%E5%BC%8F
    // 模式，可选 <default|simple>，默认 default
    mode: {
        type: String,
        default: () => "default",
    },
    // 高度
    height: {
        type: String,
        default: () => "310px",
    },
    // 双向绑定，用于获取 editor.getHtml()
    getHtml: String,
    // 双向绑定，用于获取 editor.getText()
    // getText: String,
})

// 定义子组件向父组件传值/事件
const emit = defineEmits(["update:getHtml", "update:getText"])

// 定义变量内容
const editorRef = shallowRef()
const state = reactive({
    editorConfig: {
        placeholder: props.placeholder,
    },
    editorVal: props.getHtml,
})

// 编辑器配置
const editorConfig: Partial<IEditorConfig> = {
    // 最长输入2000字
    maxLength: 2000,
    // 进入页面不自动聚焦
    autoFocus: true,
    MENU_CONF: {},
}

// 上传图片
editorConfig.MENU_CONF
    ? (editorConfig.MENU_CONF["uploadImage"] = {
          async customUpload(file: any, insertFn: any) {
              upLoadImgVideo("1", file, insertFn)
          },
      })
    : {}

// 上传视频
editorConfig.MENU_CONF
    ? (editorConfig.MENU_CONF["uploadVideo"] = {
          async customUpload(file: any, insertFn: any) {
              upLoadImgVideo("2", file, insertFn)
          },
      })
    : {}

// 封装 - 上传图片、视频
const upLoadImgVideo = (type: string, file: any, insertFn: any) => {
    if (file.size / 1024 / 1024 > 50) {
        ElMessage.error(`文件大小不能超过50MB!`)
        return false
    } else {
        // 这里根据自己的需求进行处理 --- S
        let formData = new FormData()
        formData.append("file", file)
        formData.append("fileType", type)
        // 这里根据自己的需求进行处理-- - E
        fileUpload(file)
            .then((res: any) => {
                if (res.code == 0) {
                    // 上传成功后拿到的路径插入到富文本编辑器中
                    insertFn(res.data.src)
                } else {
                    ElMessage.warning(`上传失败`)
                }
            })
            .catch(() => {
                ElMessage.warning(`上传失败`)
            })
    }
}

// 编辑器回调函数
const handleCreated = (editor: IDomEditor) => {
    editorRef.value = editor
}
// 编辑器内容改变时
const handleChange = (editor: IDomEditor) => {
    emit("update:getHtml", editor.getHtml())
    // emit("update:getText", editor.getText())
}
// 清空编辑器内容
const handleClear = () => {
    const editor = editorRef.value
    if (editor) {
        editor.clear()
    }
}
// 页面销毁时
onBeforeUnmount(() => {
    const editor = editorRef.value
    if (editor == null) return
    editor.destroy()
})
// 监听是否禁用改变
// https://gitee.com/lyt-top/vue-next-admin/issues/I4LM7I
watch(
    () => props.disable,
    (bool) => {
        const editor = editorRef.value
        if (editor == null) return
        bool ? editor.disable() : editor.enable()
    },
    {
        deep: true,
    }
)
// 监听双向绑定值改变，用于回显
watch(
    () => props.getHtml,
    (val) => {
        state.editorVal = val
    },
    {
        deep: true,
    }
)

defineExpose({ handleClear })
</script>
